from flask import Flask, render_template, request, redirect, send_file,url_for,flash,jsonify,make_response
from flask_sqlalchemy import SQLAlchemy
import os
import csv
import io
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
# from src.Tool.csv_vision import SentimentAnalysisVisualizer
# from sentiment_analysis import analysis_results
app=Flask(__name__)
# 设置一个安全的随机密钥
app.secret_key = '1815'  # 这里替换为你自己的密钥
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'  # 未登录用户访问受保护页面时跳转到的视图

# 配置 SQLite 数据库
basedir = os.path.abspath(os.path.dirname(__file__))  # 获取当前文件所在的绝对路径
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data', 'database.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化 SQLAlchemy 对象
db = SQLAlchemy(app)

# 用户模型
class User(db.Model, UserMixin):
    user_id = db.Column(db.String(80), unique=True, nullable=False,primary_key=True) #unique=True: 该参数表示该字段的值在数据库中必须是唯一的
    password = db.Column(db.String(128), nullable=False) #nullable=False: 该参数表示该字段不能为空
    is_admin = db.Column(db.Boolean, default=False)
    username=db.Column(db.String(100),nullable=True,default=None)
    email = db.Column(db.String(120), unique=True, nullable=True, default=None)  # 邮箱，唯一，允许为空
    bio = db.Column(db.Text, nullable=True, default=None)  # 个人简介，文本类型，允许为空
    province = db.Column(db.String(100), nullable=True, default=None)  # 所在省市
    city = db.Column(db.String(100), nullable=True, default=None)  # 所在城市
    district = db.Column(db.String(100), nullable=True, default=None)  # 所在区
    street_address = db.Column(db.String(200), nullable=True, default=None)  # 街道地址
    phone_number = db.Column(db.String(20), nullable=True, default=None)  # 联系电话

    # 定义 get_id 方法返回用户唯一标识符
    def get_id(self):
        return self.user_id  # 这里返回用户的 username 作为唯一标识符

    @property
    def is_active(self):
        return True

# 课程模型
class Course(db.Model):
    courseId = db.Column(db.String(50), primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    enrollCount = db.Column(db.Integer, nullable=False)
    teacherName = db.Column(db.String(100), nullable=False)
    schoolName = db.Column(db.String(100), nullable=False)
    comments = db.relationship('CourseComment', backref='course', lazy=True)

# 课程评论模型
class CourseComment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    courseId = db.Column(db.String(50), db.ForeignKey('course.courseId'), nullable=False)
    userNickName = db.Column(db.String(100))
    commentorId = db.Column(db.String(50))
    content = db.Column(db.Text, nullable=False)
    mark = db.Column(db.Integer)
    status = db.Column(db.String(50))

# 在第一次请求之前创建所有表
@app.before_request
def create_tables():
    db.create_all()

# 定义从用户ID加载用户的回调函数
@login_manager.user_loader
def load_user(user_id):
    return User.query.filter_by(user_id=user_id).first()

@app.route("/")
def index():
    return render_template('index.html')

# 登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user_id = request.form['user_id']
        password = request.form['password']
        user = User.query.filter_by(user_id=user_id).first()

        # 验证用户和密码
        if user and check_password_hash(user.password, password):
            login_user(user)  # 登录用户
            if user.is_admin:
                return redirect(url_for('admin'))   # 如果是管理员，可以重定向到管理员页面
            else:
                return redirect(url_for('dashboard'))  # 修改为主页面
        else:
            flash('用户名或密码错误！', 'danger')
            return redirect(url_for('login'))

    return render_template('index.html')  # 在 GET 请求时渲染登录页面

# 注册

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        user_id = request.form['user_id']
        password = request.form['password']
        # email = request.form['email']
        confirm_password = request.form['confirm_password']

        # 验证密码
        if password != confirm_password:
            flash('密码不匹配！', 'danger')
            return redirect(url_for('register'))

        # 检查用户账号是否已存在
        if User.query.filter_by(user_id=user_id).first():
            flash('用户名已存在！', 'danger')
            return redirect(url_for('register'))

        # # 检查邮箱是否已存在
        # if User.query.filter_by(email=email).first():
        #     flash('该邮箱已被注册！', 'danger')
        #     return redirect(url_for('register'))

        # 创建用户并保存到数据库
        hashed_password = generate_password_hash(password, method='pbkdf2:sha256')
        new_user = User(user_id=user_id, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()

        flash('注册成功！请登录。', 'success')
        return redirect(url_for('login'))

    return render_template('index.html')  # 在 GET 请求时渲染注册页面

@app.route('/dashboard')
@login_required
def dashboard():
    user = db.session.get(User, current_user.user_id)
    flash('亲爱的用户，欢迎您！', 'success')
    return render_template('dashboard.html',user=user)

@app.route('/admin')
@login_required
def admin():
    user = db.session.get(User, current_user.user_id)
    return render_template('admin_dashboard.html', user=user)

@app.route('/admin/table')
@login_required
def table():
    user = db.session.get(User, current_user.user_id)
    users=User.query.all()
    all_courses = Course.query.all()
    return render_template('tables_data.html', users=users,user=user,courses=all_courses)

# 个人中心
@app.route('/dashboard/center', methods=['GET', 'POST'])
@login_required
def center():
    user = db.session.get(User, current_user.user_id)  # 获取当前用户信息

    # 检查用户名是否与用户 ID 一致
    if user.username != str(current_user.user_id):
        user.username = str(current_user.user_id)  # 将用户名设置为用户 ID
        db.session.commit()  # 提交更改

    if request.method == 'POST':
        # 更新用户信息
        user.username = request.form['username']

        # # 处理密码哈希
        # password = request.form['password']
        # if password:  # 仅在用户输入新密码时进行更新
        #     user.password = generate_password_hash(password, method='pbkdf2:sha256')

        # 安全地获取表单字段
        user.email = request.form.get('email')  # 使用 .get() 避免 KeyError
        user.bio = request.form.get('bio')
        user.province = request.form.get('province')
        user.city = request.form.get('city')
        user.district=request.form.get('district')
        user.street_address = request.form.get('street_address')
        user.phone_number = request.form.get('phone_number')

        db.session.commit()  # 提交更改
        # flash('用户信息更新成功！', 'success')  # 可选：显示消息
        return redirect(url_for('center'))  # 重定向到个人中心

    return render_template('center.html', user=user)  # GET 请求返回用户信息

@app.route('/dashboard/center/changepass', methods=['GET', 'POST'])  # 支持 GET 和 POST 方法
@login_required  # 确保用户已登录
def changepass():
    if request.method == 'POST':
        # 处理 POST 请求中的修改密码逻辑
        data = request.get_json()
        old_password = data.get('oldPassword')
        new_password = data.get('newPassword')

        # 获取当前用户信息
        user = User.query.get(current_user.user_id)

        # 验证旧密码是否正确
        if not check_password_hash(user.password, old_password):
            return jsonify({'success': False, 'message': '旧密码不正确'}), 400

        # 更新为新密码
        user.password = generate_password_hash(new_password, method='pbkdf2:sha256')
        db.session.commit()

        return jsonify({'success': True}), 200

    # 如果是 GET 请求，返回修改密码的页面
    return render_template('changepass.html')
# 历史记录
@app.route('/dashboardrd/history')
@login_required
def history():
    return render_template('history.html')

@app.route('/dashboardrd/history/historyDetail')
@login_required
def historyDetail():
    return render_template('historyDetail.html')

# 智能体选择
@app.route('/dashboard/choose')
@login_required
def choose():
    return render_template('choose.html')

# 使用指南
@app.route('/dashboard/guide')
@login_required
def guide():
    return render_template('guide.html')

# 注销
@app.route('/logout')
@login_required  # 确保用户登录后才能访问
def logout():
    logout_user()  # 注销当前用户
    flash('您已成功退出登录!', 'success')  # 提示信息
    return redirect(url_for('login'))  # 重定向到登录页面

@app.route('/search_course', methods=['GET'])
@login_required  # 确保用户登录后才能访问
def search_course():
    course_name = request.args.get('name', '')
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 5))

    course = Course.query.filter_by(name=course_name).first()

    if course:
        comments_query = CourseComment.query.filter_by(courseId=course.courseId)
        total_comments = comments_query.count()
        pagination = comments_query.paginate(page=page, per_page=per_page, error_out=False)
        comments = pagination.items

        return jsonify({
            "success": True,
            "course": {
                "courseId": course.courseId,
                "name": course.name,
                "enrollCount": course.enrollCount,
                "teacherName": course.teacherName,
                "schoolName": course.schoolName,
                "comments": [
                    {
                        "userNickName": comment.userNickName,
                        "content": comment.content,
                        "mark": comment.mark
                    }
                    for comment in comments
                ],
                "totalComments": total_comments,
                "currentPage": pagination.page,
                "totalPages": pagination.pages
            }
        })
    else:
        return jsonify({"success": False, "message": "未找到相关课程"})


@app.route('/download_csv', methods=['GET'])
def download_csv():
    course_name = request.args.get('name')
    all_comments = CourseComment.query.join(Course).filter(Course.name == course_name).all()

    # 生成完整的 CSV 文件内容
    csv_buffer = io.StringIO()
    csv_writer = csv.writer(csv_buffer)
    csv_writer.writerow(['Course ID', 'Course Name', 'Enroll Count', 'Teacher', 'School', 'User Nickname', 'Comment', 'Mark'])

    for comment in all_comments:
        course = comment.course
        csv_writer.writerow([
            course.courseId,
            course.name,
            course.enrollCount,
            course.teacherName,
            course.schoolName,
            comment.userNickName,
            comment.content,
            comment.mark if comment.mark else 'No Rating'
        ])

    response = make_response(csv_buffer.getvalue())
    response.headers["Content-Disposition"] = "attachment; filename=course_results.csv"
    response.headers["Content-type"] = "text/csv"
    return response

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=1815, debug=True)

#
# 查询导入函数
#
# import csv
# from app import app, db, Course, CourseComment  # 从 app.py 中导入 app 和 db 对象
#
# def import_courses():
#     if Course.query.count() == 0:
#         with open('course_data.csv', newline='', encoding='gbk') as csvfile:
#             reader = csv.DictReader(csvfile)
#             for row in reader:
#                 course = Course(
#                     courseId=row['courseId'],
#                     name=row['name'],
#                     enrollCount=int(row['enrollCount']),
#                     teacherName=row['teacherName'],
#                     schoolName=row['schoolName']
#                 )
#                 db.session.add(course)
#             db.session.commit()
#         print("Courses imported successfully.")
#
# def import_comments():
#     if CourseComment.query.count() == 0:
#         with open('course_comment_data.csv', newline='', encoding='gb18030') as csvfile:
#             reader = csv.DictReader(csvfile)
#             for row in reader:
#                 comment = CourseComment(
#                     id=int(row['id']),
#                     courseId=row['courseId'],
#                     commentorId=row['commentorId'],
#                     userNickName=row['userNickName'],
#                     content=row['content'],
#                     mark=int(row['mark']) if row['mark'].isdigit() else None,
#                     status=row['status']
#                 )
#                 db.session.add(comment)
#             db.session.commit()
#         print("Comments imported successfully.")
#
# if __name__ == "__main__":
#     with app.app_context():  # 确保在应用上下文中运行
#         db.create_all()  # 创建数据库表
#         import_courses()  # 导入课程数据
#         import_comments()  # 导入评论数据